package com.scs.application.core.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.XmlUtil;
import com.scs.application.modules.sys.model.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
import java.util.Map;

/**
 *  xml工具类
 */
@Slf4j
public class UtilXml {
	/**
     * 将pojo转换为XML字符串,转换后全部为
     * @param object
     * @param isFormart		true:格式化xml
     * @param noXmlVersion	true:不包含版本信息，即去掉version行
     * @return
     */
    public static String beanToXml(Object object,boolean isFormart,boolean noXmlVersion) {
        Writer sw = new StringWriter();
        String strRet="";
        try {
            // 利用jdk中自带的转换类实现
            JAXBContext context = JAXBContext.newInstance(object.getClass());

            Marshaller marshaller = context.createMarshaller();
            // 格式化xml输出的格式
            if(isFormart) marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

            // 将对象转换成输出流形式的xml
            marshaller.marshal(object, sw);

            if(sw!=null) strRet=sw.toString();
            if(noXmlVersion) strRet=strRet.replace("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>", "");

            //去掉第一个回车字符
            if(strRet.startsWith("\n"))strRet=strRet.replaceFirst("\n", "");
        } catch (JAXBException e) {
            e.printStackTrace();
        } finally {
            if(sw != null) {
                try {
                    sw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return strRet;
    }

    /**
     * 将XML字符串转换为javabena，将会替换数据里面的\n
     *
     * @param clazz
     * @param xmlStr
     * @return
     */
    public static Object xmlToBean(Class clazz, String xmlStr) {
    	  Object xmlObject = null;
          Reader reader = null;
          try {
              JAXBContext context = JAXBContext.newInstance(clazz);
              // 进行将Xml转成对象的核心接口
              Unmarshaller unmarshaller = context.createUnmarshaller();
              xmlStr= xmlStr.replaceAll("\n","");
              reader = new StringReader(xmlStr);

              xmlObject = unmarshaller.unmarshal(reader);
          } catch (JAXBException e) {
              e.printStackTrace();
              log.error("xmlToBean error",e);
          } finally {
              if (null != reader) {
                  try {
                      reader.close();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
              }
          }
          return xmlObject;
    }

    /**
     * 将XML字符串转换为javabena，将会替换数据里面的\n
     *
     * @param clazz
     * @param xmlStr
     * @return
     */
    public static Object xmlToBeanByHuTool(Class clazz, String xmlStr) {
        //获取文档
        Document document = XmlUtil.parseXml(xmlStr);
        //获取根节点
        Element elementG = XmlUtil.getRootElement(document);

        //方式1：使用根节点下的直接 转成对象
        return XmlUtil.xmlToBean(elementG, clazz);
    }

    /**
     * 将pojo转换为XML字符串,转换后全部为
     * @param restResult
     * @param dataTransfer true 将data对象也转换成xml格式
     * @return
     */
    public static String beanToXmlForRestResult(RestResult restResult,boolean dataTransfer) {
        if (dataTransfer && restResult.getData() != null) {
            Map<String, Object> dataMap =  BeanUtil.beanToMap(restResult.getData(), false, false);
            String xmlData = XmlUtil.mapToXmlStr(dataMap,"data","", true);
            //<data>  </data>
            if (xmlData.indexOf("<data>") != -1 && xmlData.indexOf("</data>") != -1) {
                xmlData = xmlData.replace("<data>", "");
                xmlData = xmlData.replace("</data>", "");
            }
            restResult.setData(xmlData);
        }
        Map<String, Object> map =  BeanUtil.beanToMap(restResult, false, true);
        return trimXml(XmlUtil.mapToXmlStr(map,"result","", true));
    }
    /**
     * 将pojo转换为XML字符串,转换后全部为
     * @param object
     * @return
     */
    private static String trimXml(String xml) {
        xml = xml.replaceAll("&lt;","<");
        xml = xml.replaceAll("&gt;",">");
        return xml;
    }
}
